<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 
<html>
<head>
<title>Painting in Qyoto</title>
<link rel="stylesheet" href="/cfg/format.css" type="text/css">
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta name="keywords" content="GUI, painting, Qt, Qyoto, Visual Basic">
<meta name="description" content="Painting in Qyoto">
<meta name="language" content="en">
<meta name="author" content="Jan Bodnar">
<meta name="distribution" content="global">

<script type="text/javascript" src="/lib/jquery.js"></script>
<script type="text/javascript" src="/lib/common.js"></script>

</head>

<body>

<div class="container">

<div id="wide_ad" class="ltow">
<script type="text/javascript"><!--
google_ad_client = "pub-9706709751191532";
/* 160x600, August 2011 */
google_ad_slot = "2484182563";
google_ad_width = 160;
google_ad_height = 600;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>

<div class="content">


<a href="/" title="Home">Home</a>&nbsp;
<a href="..">Contents</a>


<h1>Painting in Qyoto</h1>

<p>
In this part of the Visual Basic Qyoto programming tutorial we will do some painting. 
</p>

<div class="center"> 
<script type="text/javascript"><!--
google_ad_client = "pub-9706709751191532";
/* horizontal */
google_ad_slot = "1734478269";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script> 
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> 
</script> 
</div> 

<p>
When do we need to paint? There are situations, when we need to create a 
widget from scratch. In such a case, we need to do painting. Or we want to 
create charts, special ornaments, effects or widget enhancements.  
</p>

<p>
The <b class="keyword">QPainter</b> class is instrumental when we do some 
painting in the Qyoto library.
Paint events are received in the <b class="keyword">PaintEvent()</b> method. 
To do custom painting, we must reimplement
this method. 
</p>


<h2>Patterns</h2>

<p>
In Qyoto, there are various patterns, that we can use to fill the interiors of shapes. 
</p>

<pre class="code">
' ZetCode Mono Visual Basic Qt tutorial
'
' This program draws nine rectangles.
' The interiors are filled with
' different built-in patterns.
'
' author jan bodnar
' last modified May 2009
' website www.zetcode.com


Imports Qyoto


Public Class VBQApp 
    Inherits QWidget

    Public Sub New()
    
        Me.SetWindowTitle("Patterns")
        
        Me.Resize(350, 280)
        Me.Move(300, 300)
        Me.Show()
        
    End Sub
    
    Protected Overrides Sub PaintEvent(ByVal e As QPaintEvent)
        
        Dim painter As New QPainter(Me)
        Me.DrawPatterns(painter)
            
        painter.End()
        
    End Sub
    
    Private Sub DrawPatterns(ByRef painter As QPainter)
    
        painter.SetPen(PenStyle.NoPen)

        painter.SetBrush(Qt.BrushStyle.HorPattern)
        painter.DrawRect(10, 15, 90, 60)

        painter.SetBrush(Qt.BrushStyle.VerPattern)
        painter.DrawRect(130, 15, 90, 60)

        painter.SetBrush(Qt.BrushStyle.CrossPattern)
        painter.DrawRect(250, 15, 90, 60)

        painter.SetBrush(Qt.BrushStyle.Dense7Pattern)
        painter.DrawRect(10, 105, 90, 60)
        
        painter.SetBrush(Qt.BrushStyle.Dense6Pattern)
        painter.DrawRect(130, 105, 90, 60)

        painter.SetBrush(Qt.BrushStyle.Dense5Pattern)
        painter.DrawRect(250, 105, 90, 60)

        painter.SetBrush(Qt.BrushStyle.BDiagPattern)
        painter.DrawRect(10, 195, 90, 60)

        painter.SetBrush(Qt.BrushStyle.FDiagPattern)
        painter.DrawRect(130, 195, 90, 60)

        painter.SetBrush(Qt.BrushStyle.DiagCrossPattern)
        painter.DrawRect(250, 195, 90, 60)
    
    End Sub

    Public Shared Sub Main(ByVal args() As String)
        Dim qapp As New QApplication(args)
        Dim app As New VBQApp
        QApplication.Exec()
    End Sub

End Class
</pre>

<p>
In the code example, we will draw nine rectangles and fill them with
different brush patterns. 
</p>


<pre class="explanation">
Protected Overrides Sub PaintEvent(ByVal e As QPaintEvent)
    
    Dim painter As New QPainter(Me)
    Me.DrawPatterns(painter)
        
    painter.End()
    
End Sub
</pre>

<p>
When the window area needs to be redrawn, the <b class="keyword">PaintEvent()</b> method
is called. This happens, when we resize the window, maximize it or minimize it etc. 
Inside this method, we create the <b class="keyword">QPainter</b> object. This object is used
to do all painting in Qyoto. The painting itself is delegated to the 
<b class="keyword">DrawPatterns()</b> method. The <b class="keyword">End()</b> method 
releases resources used when doing painting.
</p>

<pre class="explanation">
painter.SetPen(PenStyle.NoPen)
</pre>

<p>
The pen object is used to draw outlines of the shapes. In our example
we will not use a pen. 
</p>

<pre class="explanation">
painter.SetBrush(Qt.BrushStyle.HorPattern)
</pre>

<p>
We set a horizontal pattern as a brush. Brush is used to 
paint the insides of shapes.
</p>

<pre class="explanation">
painter.DrawRect(10, 15, 90, 60)
</pre>

<p>
We draw a rectangle, with the current pen and brush.
The first two parameters of the method are the x, y coordinates.
The last two parameters are the width and height of the rectangle. 
</p>


<br>
<img src="/img/gui/vbqyoto/patterns.png" alt="Patterns">
<div class="figure">Figure: Patterns</div>


<h2>Shapes</h2>

<p>
The Qyoto painting API can draw various shapes. The following programming code example will show some of them. 
</p>

<pre class="code">
' ZetCode Mono Visual Basic Qt tutorial
'
' This program draws basic shapes
' available in Qyoto.
'
' author jan bodnar
' last modified May 2009
' website www.zetcode.com


Imports Qyoto


Public Class VBQApp 
    Inherits QWidget

    Public Sub New()
    
        Me.SetWindowTitle("Shapes")
        
        Me.Resize(350, 280)
        Me.Move(300, 300)
        Me.Show()
        
    End Sub
    
    Protected Overrides Sub PaintEvent(ByVal e As QPaintEvent)
        
        Dim painter As New QPainter(Me)
        Me.DrawShapes(painter)
            
        painter.End()
        
    End Sub
    
    Private Sub DrawShapes(ByRef painter As QPainter)
    
        painter.SetRenderHint(QPainter.RenderHint.Antialiasing)
        painter.SetPen(New QPen(New QBrush(New QColor("Gray")), 1))
        painter.SetBrush(New QBrush(New QColor("Gray")))

        Dim path1 As New QPainterPath()

        path1.MoveTo(5, 5)
        path1.CubicTo(40, 5,  50, 50,  99, 99)
        path1.CubicTo(5, 99,  50, 50,  5, 5)
        painter.DrawPath(path1)
        
        painter.DrawPie(130, 20, 90, 60, 30*16, 120*16)
        painter.DrawChord(240, 30, 90, 60, 0, 16*180)
        painter.DrawRoundRect(20, 120, 80, 50)

        Dim polygon As New QPolygon(5)
        polygon.SetPoint(0, 130, 140)
        polygon.SetPoint(1, 180, 170)
        polygon.SetPoint(2, 180, 140)
        polygon.SetPoint(3, 220, 110)
        polygon.SetPoint(4, 140, 100)

        painter.DrawPolygon(polygon)
        painter.DrawRect(250, 110, 60, 60)

        Dim baseline As New QPointF(20, 250)
        Dim font As New QFont("Georgia", 55)
        Dim path2 As New QPainterPath()
        
        path2.AddText(baseline, font, "Q")
        painter.DrawPath(path2)

        painter.DrawEllipse(140, 200, 60, 60)
        painter.DrawEllipse(240, 200, 90, 60)
    
    End Sub

    Public Shared Sub Main(ByVal args() As String)
        Dim qapp As New QApplication(args)
        Dim app As New VBQApp
        QApplication.Exec()
    End Sub

End Class
</pre>

<p>
In this code example, we draw nine different shapes on the window. A complex path, 
a pie, a chord, a rounded rectangle, a polygon, a rectangle, a character based shape,
a circle and an ellipse. 
</p>


<pre class="explanation">
painter.SetRenderHint(QPainter.RenderHint.Antialiasing)
</pre>

<p>
We use antialiasing in the example. Antialiased shapes look better, but it takes more 
time to draw them. 
</p>

<pre class="explanation">
painter.SetPen(New QPen(New QBrush(New QColor("Gray")), 1))
painter.SetBrush(New QBrush(New QColor("Gray")))
</pre>

<p>
We use a dark gray pen and brush to draw the shapes. 
</p>

<pre class="explanation">
Dim path1 As New QPainterPath()

path1.MoveTo(5, 5)
path1.CubicTo(40, 5,  50, 50,  99, 99)
path1.CubicTo(5, 99,  50, 50,  5, 5)
painter.DrawPath(path1)
</pre>

<p>
The first complex shape is created with the <b class="keyword">QPainterPath</b> object. 
The QPainterPath class provides a container for painting operations. A painter path is an 
object composed of a number of graphical building blocks, such as rectangles, ellipses, 
lines, and curves.
</p>

<pre class="explanation">
painter.DrawPie(130, 20, 90, 60, 30*16, 120*16)
painter.DrawChord(240, 30, 90, 60, 0, 16*180)
painter.DrawRoundRect(20, 120, 80, 50)
</pre>

<p>
These three lines draw a pie, a chord and a rounded rectangle. 
</p>

<pre class="explanation">
Dim polygon As New QPolygon(5)
polygon.SetPoint(0, 130, 140)
polygon.SetPoint(1, 180, 170)
polygon.SetPoint(2, 180, 140)
polygon.SetPoint(3, 220, 110)
polygon.SetPoint(4, 140, 100)

painter.DrawPolygon(polygon)
</pre>

<p>
Here we create a polygon.
</p>

<pre class="explanation">
Dim baseline As New QPointF(20, 250)
Dim font As New QFont("Georgia", 55)
Dim path2 As New QPainterPath()

path2.AddText(baseline, font, "Q")
painter.DrawPath(path2)
</pre>

<p>
These lines create a character based shape. 
</p>

<pre class="explanation">
painter.DrawEllipse(140, 200, 60, 60)
painter.DrawEllipse(240, 200, 90, 60)
</pre>

<p>
These two lines create a circle and an ellipse respectively.
</p>

<br>
<img src="/img/gui/vbqyoto/shapes.png" alt="Shapes">
<div class="figure">Figure: Shapes</div>


<h2>Transparent rectangles</h2>

<p>
Transparency is the quality of being able to see through a material.
The easiest way to understand transparency is to imagine a piece of
glass or water. Technically, the rays of light can go through the 
glass and this way we can see objects behind the glass.
</p>

<p>
In computer graphics, we can achieve transparency effects using alpha compositing.
 Alpha compositing is the process of combining an image with a background 
to create the appearance of partial transparency. 
The composition process uses an alpha channel. (wikipedia.org, answers.com) 
</p>

<pre class="code">
' ZetCode Mono Visual Basic Qt tutorial
'
' This program draws ten
' rectangles with different
' levels of transparency
'
' author jan bodnar
' last modified May 2009
' website www.zetcode.com


Imports Qyoto


Public Class VBQApp 
    Inherits QWidget

    Public Sub New()
    
        Me.SetWindowTitle("Transparent rectangles")
        
        Me.Resize(590, 90)
        Me.Move(300, 300)
        Me.Show()
        
    End Sub
    
    Protected Overrides Sub PaintEvent(ByVal e As QPaintEvent)
        
        Dim painter As New QPainter(Me)
        Me.DrawRectangles(painter)
            
        painter.End()
        
    End Sub
    
    Private Sub DrawRectangles(ByRef painter As QPainter)
    
        painter.SetPen(PenStyle.NoPen)

        For i As Integer = 1 To 10
            painter.SetBrush(New QBrush(New QColor(0, 0, 255, i*25)))
            painter.DrawRect(50*i, 20, 40, 40)
        Next

    End Sub

    Public Shared Sub Main(ByVal args() As String)
        Dim qapp As New QApplication(args)
        Dim app As New VBQApp
        QApplication.Exec()
    End Sub

End Class
</pre>

<p>
In the example we will draw ten rectangles with different levels of transparency. 
</p>


<pre class="explanation">
painter.SetPen(PenStyle.NoPen)
</pre>

<p>
We use no pen. 
</p>

<pre class="explanation">
For i As Integer = 1 To 10
    painter.SetBrush(New QBrush(New QColor(0, 0, 255, i*25)))
    painter.DrawRect(50*i, 20, 40, 40)
Next
</pre>

<p>
The last parameter of the <b class="keyword">QColor</b> object is the alpha transparency value. 
</p>


<br>
<img src="/img/gui/vbqyoto/trect.png" alt="Transparent rectangles">
<div class="figure">Figure: Transparent rectangles</div>


<h2>Donut Shape</h2>

<p>
In the following example we create a complex shape by rotating a bunch of ellipses. 
</p>

<pre class="code">
' ZetCode Mono Visual Basic Qt tutorial
'
' This program draws a donut
' shape
'
' author jan bodnar
' last modified May 2009
' website www.zetcode.com


Imports Qyoto


Public Class VBQApp 
    Inherits QWidget

    Public Sub New()
    
        Me.SetWindowTitle("Donut")
        
        Me.Resize(350, 280)
        Me.Move(300, 300)
        Me.Show()
        
    End Sub
    
    Protected Overrides Sub PaintEvent(ByVal e As QPaintEvent)
        
        Dim painter As New QPainter(Me)
        Me.DrawDonut(painter)
            
        painter.End()
        
    End Sub
    
    Private Sub DrawDonut(ByRef painter As QPainter)
    
        Dim color As New QColor()
        color.SetNamedColor("#333333")

        Dim pen As New QPen(color)
        pen.setWidthF(0.5)
        painter.SetPen(pen)
        
        painter.SetRenderHint(QPainter.RenderHint.Antialiasing)

        Dim h As Integer = Me.Height()
        Dim w As Integer = Me.Width()
        
        painter.Translate(New QPoint(w/2, h/2))

        For rot As Integer = 1 To 360 Step 5
            painter.DrawEllipse(-125, -40, 250, 80)
            painter.Rotate(5)
        Next

    End Sub

    Public Shared Sub Main(ByVal args() As String)
        Dim qapp As New QApplication(args)
        Dim app As New VBQApp
        QApplication.Exec()
    End Sub

End Class
</pre>

<p>
In this example, we create a donut. The shape resembles a cookie, hence the name donut. 
</p>


<pre class="explanation">
Dim color As New QColor()
color.SetNamedColor("#333333")
</pre>

<p>
We can use a hexadecimal notation to create a color object. 
</p>

<pre class="explanation">
Dim h As Integer = Me.Height()
Dim w As Integer = Me.Width()
</pre>

<p>
Here we determine the width and height of the window. 
</p>

<pre class="explanation">
painter.Translate(New QPoint(w/2, h/2))
</pre>

<p>
We move the coordinate system to the middle of the window. This way we
make the drawing mathematically easier. 
</p>

<pre class="explanation">
For rot As Integer = 1 To 360 Step 5
    painter.DrawEllipse(-125, -40, 250, 80)
    painter.Rotate(5)
Next
</pre>

<p>
We draw an ellipse object 72 times. Each time, we rotate the
ellipse by 5 degrees. This will create our donut shape.
</p>


<br>
<img src="/img/gui/vbqyoto/donut.png" alt="Donut">
<div class="figure">Figure: Donut</div>


<h2>Drawing text</h2>

<p>
In the last example, we are going to draw text
on the window. 
</p>

<pre class="code">
' ZetCode Mono Visual Basic Qt tutorial
'
' This program draws text
' on the window
'
' author jan bodnar
' last modified May 2009
' website www.zetcode.com


Imports Qyoto


Public Class VBQApp 
    Inherits QWidget

    Public Sub New()
    
        Me.SetWindowTitle("Unfaitful")
        
        Me.Resize(300, 280)
        Me.Move(300, 300)
        Me.Show()
        
    End Sub
    
    Protected Overrides Sub PaintEvent(ByVal e As QPaintEvent)
        
        Dim painter As New QPainter(Me)
        Me.DrawLyrics(painter)
            
        painter.End()
        
    End Sub
    
    Private Sub DrawLyrics(ByRef painter As QPainter)
    
        painter.SetBrush(New QBrush(new QColor(25, 25, 25)))
        painter.SetFont(New QFont("Purisa", 10))

        painter.DrawText(New QPoint(20, 30), _
                "I don't wanna do this anymore")
        painter.DrawText(New QPoint(20, 60), _
                "I don't wanna be the reason why")
        painter.DrawText(New QPoint(20, 90), _
                "Everytime I walk out the door")
        painter.DrawText(New QPoint(20, 120), _
                "I see him die a little more inside")
        painter.DrawText(New QPoint(20, 150), _
                "I don't wanna hurt him anymore")
        painter.DrawText(New QPoint(20, 180), _
                "I don't wanna take away his life")
        painter.DrawText(New QPoint(20, 210), _
                "I don't wanna be...") 
        painter.DrawText(New QPoint(20, 240), _
                "A murderer")

    End Sub

    Public Shared Sub Main(ByVal args() As String)
        Dim qapp As New QApplication(args)
        Dim app As New VBQApp
        QApplication.Exec()
    End Sub

End Class
</pre>

<p>
We draw a song lyrics on the window. 
</p>

<pre class="explanation">
painter.SetFont(New QFont("Purisa", 10))
</pre>

<p>
We set a Purisa font for our text. 
</p>

<pre class="explanation">
painter.DrawText(New QPoint(20, 30), _
        "I don't wanna do this anymore")
</pre>

<p>
The <b class="keyword">DrawText()</b> method is used
to draw the text. 
</p>


<br>
<img src="/img/gui/vbqyoto/soulmate.png" alt="Drawing text">
<div class="figure">Figure: Drawing text</div>

<p>
In this part of the Visual Basic Qyoto programming tutorial, we did some
painting.
</p>

<hr class="btm">

<div class="center"> 
<script type="text/javascript"><!--
google_ad_client = "pub-9706709751191532";
/* horizontal */
google_ad_slot = "1734478269";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script> 
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> 
</script> 
</div> 
<br> 


<div class="botNav, center">
<span class="botNavItem"><a href="/">Home</a></span> ‡ <span class="botNavItem"><a href="..">Contents</a></span> ‡ 
<span class="botNavItem"><a href="#">Top of Page</a></span>
</div>


<div class="footer">
<div class="signature">
<a href="/">ZetCode</a> last modified May 17, 2009  <span class="copyright">&copy; 2007 - 2012 Jan Bodnar</span>
</div>
</div>

</div> <!-- content -->

</div> <!-- container -->

</body>
</html>


